home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
src
/
haeberli
/
fonttools
/
totype1.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
14KB
|
616 lines
/*
* Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
* All Rights Reserved.
*
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
* the contents of this file may not be disclosed to third parties, copied or
* duplicated in any form, in whole or in part, without the prior written
* permission of Silicon Graphics, Inc.
*
* RESTRICTED RIGHTS LEGEND:
* Use, duplication or disclosure by the Government is subject to restrictions
* as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
* and Computer Software clause at DFARS 252.227-7013, and/or in similar or
* successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
* rights reserved under the Copyright Laws of the United States.
*/
/*
* totype1: convert an outline font into a PostScript font.
*
* Paul Haeberil and Seth Teller
*
*/
#include "math.h"
#include "ctype.h"
#include "stdio.h"
#include "objfnt.h"
static void makefontname();
static void writepsfile();
main(argc,argv)
int argc;
char **argv;
{
objfnt *fnt;
char fontname[256];
if( argc<3 ) {
fprintf(stderr,"usage: totype1 font.of type1font [font.afm]\n");
exit(1);
}
fnt = readobjfnt(argv[1]);
if(!fnt ) {
fprintf(stderr,"totype1: can't open input font\n");
exit(1);
}
if(fnt->type != PO_TYPE && fnt->type != SP_TYPE) {
fprintf(stderr,"totype1: input font must be Polygon or Spline outline\n");
exit(1);
}
makefontname(argv[2],fontname);
writepsfile(fnt,fontname,argv[2]);
if(argc>3)
writeafmfile(fnt,fontname,argv[3]);
exit(0);
}
#define DATABUFLEN (32)
static unsigned char databuf[DATABUFLEN];
#define MAXPROGLEN (4096)
static unsigned char type1prog[MAXPROGLEN];
#define NOTDEFLEN (9)
static unsigned char notdefprog[NOTDEFLEN] = {
0x00, 0x01, 0x02, 0x03,
0x8b, 0xf7, 0x8e, 0x0d, 0x0e,
};
static int firsted;
/*
* program opcodes:
*
*
*/
#define HSTEM (1)
#define VSTEM (3)
#define VMOVETO (4)
#define RLINETO (5)
#define HLINETO (6)
#define VLINETO (7)
#define RRCURVETO (8)
#define CLOSEPATH (9)
#define CALLSUBR (10)
#define RETURN (11)
#define HSBW (13)
#define ENDCHAR (14)
#define RMOVETO (21)
#define HMOVETO (22)
#define VHCURVETO (30)
#define HVCURVETO (31)
#define DOTSECTION (256+0)
#define VSTEM3 (256+1)
#define HSTEM3 (256+2)
#define SEAC (256+6)
#define SBW (256+7)
#define DIV (256+12)
#define CALLOTHERSUBR (256+16)
#define POP (256+17)
#define SETCURRENTPOINT (256+33)
#define WHAT0 (0)
/*
* Encryption support
*
*/
static unsigned short mr;
static void resetencrypt(int n)
{
mr = n;
}
static void encryptdata(unsigned char *iptr,unsigned char *optr,int n)
{
unsigned char in;
unsigned short mymr;
unsigned short c1;
unsigned short c2;
mymr = mr;
c1 = 52845;
c2 = 22719;
while(n>8) {
in = iptr[0];
optr[0] = (in^(mymr>>8));
mymr = (optr[0]+mymr)*c1 + c2;
in = iptr[1];
optr[1] = (in^(mymr>>8));
mymr = (optr[1]+mymr)*c1 + c2;
in = iptr[2];
optr[2] = (in^(mymr>>8));
mymr = (optr[2]+mymr)*c1 + c2;
in = iptr[3];
optr[3] = (in^(mymr>>8));
mymr = (optr[3]+mymr)*c1 + c2;
in = iptr[4];
optr[4] = (in^(mymr>>8));
mymr = (optr[4]+mymr)*c1 + c2;
in = iptr[5];
optr[5] = (in^(mymr>>8));
mymr = (optr[5]+mymr)*c1 + c2;
in = iptr[6];
optr[6] = (in^(mymr>>8));
mymr = (optr[6]+mymr)*c1 + c2;
in = iptr[7];
optr[7] = (in^(mymr>>8));
mymr = (optr[7]+mymr)*c1 + c2;
n-=8;
optr+=8;
iptr+=8;
}
while(n--) {
in = iptr[0];
optr[0] = (in^(mymr>>8));
mymr = (optr[0]+mymr)*c1 + c2;
optr++;
iptr++;
}
mr = mymr;
}
static int encryptprogram(unsigned char *buf,int len)
{
resetencrypt(4330);
encryptdata(buf,buf,len);
}
static void makefontname(filename,fontname)
char *filename, *fontname;
{
int n;
char *cptr, *slashptr, *dptr;
cptr = filename;
slashptr = 0;
while(*cptr) {
if(*cptr == '/')
slashptr = cptr;
cptr++;
}
if(slashptr)
cptr = slashptr+1;
else
cptr = filename;
dptr = fontname;
while(*cptr) {
if(*cptr == '.')
break;
*dptr++ = *cptr++;
}
*dptr = 0;
}
static int makeid(name)
unsigned char *name;
{
int hash;
hash = 0;
while(*name) {
hash = (hash<<1)^(*name++);
}
hash = hash%20000;
return hash+40000;
}
static void puthexdata(outf,buf,n)
FILE *outf;
unsigned char *buf;
int n;
{
while(n--)
fprintf(outf,"%02x",*buf++);
fprintf(outf,"\n");
}
static unsigned char *outpos;
static int curx, cury;
static void OP_PUSHVAL(val)
int val;
{
int high;
if(val>=-107 && val<=107) {
*outpos++ = val+139;
} else if(val>0 && val<=1131) {
val = val-108;
high = val/256;
*outpos++ = 247+high;
*outpos++ = val-(256*high);
} else if(val<0 && val>=-1131) {
val = -val;
val = val-108;
high = val/256;
*outpos++ = 251+high;
*outpos++ = val-(256*high);
} else {
*outpos++ = 255;
*outpos++ = (val>>24)&0xff;
*outpos++ = (val>>16)&0xff;
*outpos++ = (val>> 8)&0xff;
*outpos++ = (val>> 0)&0xff;
}
}
static void OP_ADDSALT()
{
*outpos++ = 0x00;
*outpos++ = 0x01;
*outpos++ = 0x02;
*outpos++ = 0x03;
}
static void OP_ENDCHAR()
{
*outpos++ = ENDCHAR;
}
static void OP_RMOVETO(dx,dy)
int dx, dy;
{
OP_PUSHVAL(dx);
OP_PUSHVAL(dy);
*outpos++ = RMOVETO;
curx = curx+dx;
cury = cury+dy;
}
static void OP_RLINETO(dx,dy)
int dx, dy;
{
OP_PUSHVAL(dx);
OP_PUSHVAL(dy);
*outpos++ = RLINETO;
curx = curx+dx;
cury = cury+dy;
}
static void OP_CLOSEPATH()
{
*outpos++ = CLOSEPATH;
}
static void OP_ADVANCE(width)
int width;
{
OP_PUSHVAL(0);
OP_PUSHVAL(width);
*outpos++ = HSBW;
curx = cury = 0;
}
static void OP_MOVETO(x,y)
int x, y;
{
OP_RMOVETO(x-curx,y-cury);
}
static void OP_LINETO(x,y)
int x, y;
{
OP_RLINETO(x-curx,y-cury);
}
static void OP_RRCURVETO(x1,y1,x2,y2,x3,y3)
int x1, y1, x2, y2, x3, y3;
{
OP_PUSHVAL(x1);
OP_PUSHVAL(y1);
OP_PUSHVAL(x2);
OP_PUSHVAL(y2);
OP_PUSHVAL(x3);
OP_PUSHVAL(y3);
*outpos++ = RRCURVETO;
curx = curx+x1+x2+x3;
cury = cury+y1+y2+y3;
}
static void OP_CURVETO(x1,y1,x2,y2,x3,y3)
int x1, y1, x2, y2, x3, y3;
{
int dx1, dy1, dx2, dy2, dx3, dy3;
int x0, y0;
x0 = curx;
y0 = cury;
dx1 = x1-x0;
dy1 = y1-y0;
dx2 = x2-x0;
dy2 = y2-y0;
dx3 = x3-x0;
dy3 = y3-y0;
dx3 = dx3-dx2;
dy3 = dy3-dy2;
dx2 = dx2-dx1;
dy2 = dy2-dy1;
OP_RRCURVETO(dx1,dy1,dx2,dy2,dx3,dy3);
}
static int maketype1prog(prog,type,advance,type1prog)
short *prog;
int type, advance;
unsigned char *type1prog;
{
int nverts, npoints;
unsigned char *initpos;
short *sptr;
outpos = type1prog;
OP_ADDSALT();
OP_ADVANCE(advance);
sptr = prog;
switch(type) {
case PO_TYPE:
npoints = 0;
while(1) {
switch(*sptr++) {
case PO_BGNLOOP:
npoints = 0;
break;
case PO_ENDBGNLOOP:
OP_CLOSEPATH();
npoints = 0;
break;
case PO_RETENDLOOP:
case PO_RET:
OP_CLOSEPATH();
OP_ENDCHAR();
return outpos-type1prog;
break;
}
nverts = *sptr++;
while(nverts--) {
if(npoints == 0)
OP_MOVETO(sptr[0],sptr[1]);
else
OP_LINETO(sptr[0],sptr[1]);
sptr+=2;
npoints++;
}
}
case SP_TYPE:
while(1) {
switch(*sptr++) {
case SP_MOVETO:
OP_MOVETO(sptr[0],sptr[1]);
sptr+=2;
break;
case SP_LINETO:
OP_LINETO(sptr[0],sptr[1]);
sptr+=2;
break;
case SP_CURVETO:
OP_CURVETO(sptr[0],sptr[1],
sptr[2],sptr[3],sptr[4],sptr[5]);
sptr+=6;
break;
case SP_CLOSEPATH:
OP_CLOSEPATH();
break;
case SP_RETCLOSEPATH:
OP_CLOSEPATH();
OP_ENDCHAR();
return outpos-type1prog;
break;
case SP_RET:
OP_ENDCHAR();
return outpos-type1prog;
break;
default:
printf("bad op %d\n",sptr[-1]);
break;
}
}
}
}
static void writepsfile(fnt,fontname,outfname)
objfnt *fnt;
char *fontname, *outfname;
{
int i, c, nbytes;
char tempfilename[256];
char cmd[256];
FILE *outf, *cf;
chardesc *cd;
short *prog;
int ndefined;
int llx, lly, urx, ury;
if(!firsted) {
encryptprogram(notdefprog,NOTDEFLEN);
firsted = 1;
}
outf = fopen(outfname,"w");
if(!outf) {
fprintf(stderr,"totype1: can't open '%s' for write!\n",outfname);
exit(1);
}
fontbbox(fnt,&llx,&lly,&urx,&ury);
/* Put out EPSF header */
fprintf(outf,"%%!PS-AdobeFont-2.0: %s 001.001\n\n",fontname);
fprintf(outf,"%% To load to VM, remove the '%' character from the 'exitserver' line.\n\n");
fprintf(outf,"%% serverdict begin 0 exitserver %% for VM installation\n\n");
/* emit the obligatory header code */
fprintf(outf,"11 dict begin\n");
fprintf(outf,"/FontInfo 10 dict dup begin\n");
fprintf(outf,"version (001.000) readonly def\n");
fprintf(outf,"/Notice (Adobe Type 1 format font) readonly def\n");
fprintf(outf,"/Copyright (This is a spot for a copywrite notice) readonly def\n");
fprintf(outf,"/FullName (SGI %s) readonly def\n",fontname);
fprintf(outf,"/FamilyName (SGI %s) readonly def\n",fontname);
fprintf(outf,"/Weight (Medium) readonly def\n");
fprintf(outf,"/ItalicAngle 0 def\n");
fprintf(outf,"/isFixedPitch false def\n");
fprintf(outf,"/UnderlinePosition -110 def\n");
fprintf(outf,"/UnderlineThickness 49 def\n");
fprintf(outf,"end readonly def\n");
fprintf(outf,"/FontName /%s def\n",fontname);
fprintf(outf,"/Encoding StandardEncoding def\n");
fprintf(outf,"/PaintType 0 def\n");
fprintf(outf,"/FontType 1 def\n");
fprintf(outf,"/FontMatrix [%g 0 0 %g 0 0] readonly def\n",
1.0/fnt->scale,1.0/fnt->scale);
fprintf(outf,"/UniqueID %d def\n",makeid(fontname));
fprintf(outf,"/FontBBox{%d %d %d %d}readonly def\n",llx,lly,urx,ury);
fprintf(outf,"currentdict end\n");
fprintf(outf,"currentfile eexec\n");
/* write out the encrypted part of the font */
sprintf(tempfilename,"/usr/tmp/totpy1XXXXXX");
mktemp(tempfilename);
cf = fopen(tempfilename,"w");
if(!cf) {
fprintf(stderr,"totype1: can't open 'temp.cf' for write!\n");
exit(1);
}
fprintf(cf,"ABCD"); /* four bytes ignored */
fprintf(cf,"dup /Private 8 dict dup begin\n");
fprintf(cf,"/-|{string currentfile exch readstring pop}executeonly def\n");
fprintf(cf,"/|-{noaccess def}executeonly def\n");
fprintf(cf,"/BlueValues [] def\n");
fprintf(cf,"/MinFeature{16 16}def\n");
fprintf(cf,"/password 5839 def\n");
fprintf(cf,"/ForceBold false def\n");
fprintf(cf,"/Subrs 0 array\n");
fprintf(cf,"|-\n");
/* define the encoding vector entries */
ndefined = 0;
ndefined++; /* space = special case */
for(c = MIN_ASCII+1; c <= MAX_ASCII; c++) {
if(getcharprog(fnt,c))
ndefined++;
}
fprintf(cf,"2 index /CharStrings %d dict dup begin\n",ndefined+1);
/* loop over the characters to output */
for(c = MIN_ASCII; c <= MAX_ASCII; c++) {
if(prog=getcharprog(fnt,c)) {
cd = getchardesc(fnt,c);
nbytes = maketype1prog(prog,fnt->type,cd->movex,type1prog);
#ifdef DEBUGGING
fprintf(stdout,"char %s nbytes: %d \n",asciiname(c),nbytes);
puthexdata(stdout, type1prog,nbytes);
fprintf(stdout,"\n\n");
#endif
encryptprogram(type1prog,nbytes);
fprintf(cf,"/%s %d -| ",asciiname(c),nbytes);
fwrite(type1prog,nbytes,1,cf);
fprintf(cf," |-\n");
}
}
fprintf(cf,"/.notdef %d -| ",NOTDEFLEN);
fwrite(notdefprog,NOTDEFLEN,1,cf);
fprintf(cf," |-\n");
fprintf(cf,"end\n");
fprintf(cf,"end\n");
fprintf(cf,"readonly put\n");
fprintf(cf,"noaccess put\n");
fprintf(cf,"dup/FontName get exch definefont pop\n");
fprintf(cf,"mark currentfile closefile\n");
fclose(cf);
/* open the date file and encrypt it into the output file */
cf = fopen(tempfilename,"r");
if(!cf) {
fprintf(stderr,"totype1: can't open 'temp.cf' for write!\n");
exit(1);
}
resetencrypt(55665);
while( (nbytes=fread(databuf,1,DATABUFLEN,cf))>0 ) {
encryptdata(databuf,databuf,nbytes);
puthexdata(outf,databuf,nbytes);
}
fclose(cf);
sprintf(cmd,"mv %s temp.log",tempfilename);
system(cmd);
unlink(tempfilename);
for(i=0; i<8; i++)
fprintf(outf,"0000000000000000000000000000000000000000000000000000000000000000\n");
fprintf(outf,"cleartomark\n");
fclose(outf);
}
writeafmfile(fnt,fontname,outfname)
objfnt *fnt;
char *fontname, *outfname;
{
FILE *outf;
int nchars;
int c, llx, lly, urx, ury;
chardesc *cd;
outf = fopen(outfname,"w");
if(!outf) {
fprintf(stderr,"totype1: can't open '%s' for write!\n",outfname);
exit(1);
}
fontbbox(fnt,&llx,&lly,&urx,&ury);
fprintf(outf,"StartFontMetrics 2.0\n");
fprintf(outf,"Comment Generated by totype1 on Silicon Graphics IRIS\n");
fprintf(outf,"FontName %s\n",fontname);
fprintf(outf,"FullName %s\n",fontname);
fprintf(outf,"FamilyName %s\n",fontname);
fprintf(outf,"Weight standard\n");
fprintf(outf,"Notice Note that there is no notice\n");
fprintf(outf,"ItalicAngle 0.0\n");
fprintf(outf,"IsFixedPitch false\n");
fprintf(outf,"UnderlinePosition -110\n");
fprintf(outf,"UnderlineThickness 49\n");
fprintf(outf,"Version 001.000\n");
fprintf(outf,"EncodingScheme AdobeStandardEncoding\n");
fprintf(outf,"FontBBox %d %d %d %d\n",llx,lly,urx,ury);
fprintf(outf,"CapHeight 662\n"); /* xxx */
fprintf(outf,"XHeight 448\n"); /* xxx */
fprintf(outf,"Descender -217\n"); /* xxx */
fprintf(outf,"Ascender 682\n"); /* xxx */
nchars = fnt->charmax-fnt->charmin;
fprintf(outf,"StartCharMetrics %d\n",nchars);
for(c=fnt->charmin; c<=fnt->charmax; c++) {
cd = getchardesc(fnt,c);
if(cd->llx == NOBBOX) {
llx = 0;
lly = 0;
urx = 0;
ury = 0;
} else {
llx = cd->llx;
lly = cd->lly;
urx = cd->urx;
ury = cd->ury;
}
if(asciiname(c))
fprintf(outf,"C %d ; WX %d ; N %s ; B %d %d %d %d ;\n",
c,cd->movex,asciiname(c),llx,lly,urx,ury);
}
fprintf(outf,"EndCharMetrics\n");
fprintf(outf,"EndFontMetrics\n");
fclose(outf);
}